package com.pm.common.utils;


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.Charsets;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class PlmSoapUtil {

    /**
     * @param url        服务地址
     * @param methodName 接口方法名
     * @param paramMap   参数
     * @param type       类型
     * @return
     * @throws DocumentException
     */
    public static Object getWebServiceAndSoap(String url, String methodName, Map<String, String> paramMap, String type) throws DocumentException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "soap+xml", Charsets.toCharset(Charset.defaultCharset())));
        StringBuffer body = getSoapString(methodName, paramMap);
        HttpEntity request = new HttpEntity(body.toString(), headers);
        ResponseEntity response = restTemplate.postForEntity(url, request, String.class, new HashMap<String, String>());
        if (response != null && response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
            return getTagOfEnglishStrFromXml(JSONObject.toJSON(response.getBody()).toString(), type);
        }
        return null;
    }

    public static Object getTagOfEnglishStrFromXml(String xml, String type) throws DocumentException {
        Document doc = DocumentHelper.parseText(xml);
        if (null == doc.getRootElement() || !doc.getRootElement().hasContent()) {
            return null;
        }
        Element root = doc.getRootElement();
        Element stringElem = (Element) root.elements().get(0);
        Element o1 = (Element) stringElem.elements().get(0);
        Element o2 = (Element) o1.elements().get(0);
        Object data = o2.getData();
        return data;
    }

    public static StringBuffer getSoapString(String methodName, Map<String, String> paramMap) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
                " xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\"><soap12:Body><" + methodName + " xmlns=\"http://tempuri.org/\">\" +\n");
        Set<Map.Entry<String, String>> entry = paramMap.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entry.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            stringBuffer.append("<" + next.getKey() + ">" + next.getValue() + "</" + next.getKey() + ">\n");
        }
        stringBuffer.append("</" + methodName + "></soap12:Body></soap12:Envelope>");
        return stringBuffer;
    }

    private static RestTemplate restTemplate;

    static {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(600000);
        requestFactory.setReadTimeout(600000);
        restTemplate = new RestTemplate(requestFactory);
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 设置编码集
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); //error处理
    }

    private static class DefaultResponseErrorHandler implements ResponseErrorHandler {
        /**
         * 对response进行判断，如果是异常情况，返回true
         */
        @Override
        public boolean hasError(ClientHttpResponse response) throws IOException {
            return response.getStatusCode().value() != HttpServletResponse.SC_OK;
        }

        /**
         * 异常情况时的处理方法
         */
        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(response.getBody()));
            StringBuilder sb = new StringBuilder();
            String str = null;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            try {
                throw new Exception(sb.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
